package me.android.library.ui.impl;

import android.app.Activity;
import android.content.ClipData;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;

import androidx.fragment.app.FragmentActivity;

import com.google.common.eventbus.AllowConcurrentEvents;
import com.google.common.eventbus.Subscribe;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import me.android.library.common.App;
import me.android.library.common.enums.ConnectivityMode;
import me.android.library.common.event.ActivityResultEvent;
import me.android.library.common.event.ConnectionModeChangedEvent;
import me.android.library.ui.UiService;
import me.android.library.ui.api.Form;
import me.android.library.ui.api.Page;
import me.android.library.utils.android.HandlerUtil;
import me.android.library.utils.android.InstallUtil;
import me.android.library.utils.android.MemoryUtil;
import mylab.base.foundation.event.AsyncEventSupporter;
import mylab.utils.common.guava.AsyncEventUtil;


@Slf4j
public abstract class AbstractActivity extends FragmentActivity implements Form, AsyncEventSupporter {

    public final static String WillShowPageKey = "WillShowPageKey";

    @Getter
    protected String formKey;
    protected App app;
    protected boolean isExit = false;

    abstract protected String createFormKey();


    @Override
    protected void onCreate(Bundle savedState) {
        super.onCreate(savedState);
        log.info("Activity onCreate:{}", this.getClass().getSimpleName());
        AsyncEventSupporter.super.registerEventListener();

        Bundle bd = getIntent().getExtras();
        String pageKey = null;
        if (bd != null) {
            pageKey = bd.getString(WillShowPageKey);
        }

        formKey = createFormKey();
        app = (App) getApplication();
        app.addActivity(this);

        requestWindowFeature();
        setContentView();
        attachActivity(pageKey);
        initOnCreate();

        if (savedState != null) {
            restoreState(savedState);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        UiService.getInstance().setTopActivity(formKey);
        log.info("top key:{}", formKey);
    }

    @Override
    protected void onDestroy() {
        app.removeActivity(this);
        AsyncEventSupporter.super.unregisterEventListener();
        UiService.getInstance().detachActivity(formKey);
        View rootView = getWindow().getDecorView().findViewById(android.R.id.content);
        MemoryUtil.disposeView(rootView);
        super.onDestroy();
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        ActivityResultEvent.ActivityResult activityResult = new ActivityResultEvent.ActivityResult(requestCode, resultCode, data);
        AsyncEventUtil.postEvent(new ActivityResultEvent(this, activityResult));
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        Page page = UiService.getInstance().getFormManager(formKey).getCurrentPage();
        if (page != null && page.onKeyDown(keyCode, event)) {
            return true;
        } else {
            return switch (keyCode) {
                case KeyEvent.KEYCODE_MENU -> {
                    onKeyDown_Menu();
                    yield true;
                }
                case KeyEvent.KEYCODE_BACK -> {
                    onKeyDown_Back();
                    yield true;
                }
                default -> super.onKeyDown(keyCode, event);
            };
        }
    }

    @AllowConcurrentEvents
    @Subscribe
    public void onConnectionModeChangedEvent(ConnectionModeChangedEvent event) {
        onConnectionModeChanged(event.getContent());
    }

    @AllowConcurrentEvents
    @Subscribe
    public void onActivityResultEvent(ActivityResultEvent event) {
        onActivityResult(event.getSource(), event.getContent());
    }

    protected void onConnectionModeChanged(ConnectivityMode mode) {
    }

    protected void onActivityResult(Activity activity, ActivityResultEvent.ActivityResult activityResult) {
        int requestCode = activityResult.getRequestCode();
        int resultCode = activityResult.getRequestCode();
        Intent intent = activityResult.getIntent();

        if (requestCode == InstallUtil.REQUEST_CODE_UNKNOWN_APP) {
            try {
                ClipData clipData = intent.getClipData();
                if (clipData != null && clipData.getItemCount() > 0) {
                    Uri uri = clipData.getItemAt(0).getUri();
                    InstallUtil.installApk(this, uri);
                }
            } catch (Exception e) {
                log.warn("onActivityResultEvent error", e);
            }
        }
    }

    protected void requestWindowFeature() {
    }

    protected void setContentView() {
    }

    protected void attachActivity(String pageKey) {
        UiService.getInstance().attachActivity(formKey, this, pageKey);
    }

    protected void initOnCreate() {
    }

    protected void restoreState(Bundle savedState) {
    }

    protected void onKeyDown_Menu() {
        FormManager fm = UiService.getInstance().getFormManager(formKey);
        if (fm != null) {
            boolean isHome = fm.isHome();
            if (isHome) {
                fm.toggleMenu();
            }
        }

    }

    protected void onKeyDown_Back() {

        FormManager fm = UiService.getInstance().getTop();
        if (fm == null) {
            exit();
        } else {
            if (fm.isHome()) {
                exit();
            } else {
                UiService.getInstance().popBack();
            }
        }

    }

    protected void exit() {
        if (!isExit) {
            isExit = true;
            showTipWhenExit();
            HandlerUtil.runOnUiThreadDelayed(() ->{
                isExit = false;
            }, 2000);

        } else {
            finish();
            app.exit();
        }
    }

    protected void showTipWhenExit() {
        // ToastUtils.showShort(R.string.app_exit);
    }

}
